package com.project.common.exception;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.MessageFormat;
import java.util.Optional;
import java.util.stream.Stream;

public final class ErrorCodes {
    private static final Logger LOGGER = LoggerFactory.getLogger(ErrorCodes.class);
    private static final int COMMON_ERROR_OFFSET = 99999;
    private static final int AUTHORIZATION_ERROR_OFFSET = 199999;
    private static final int FOUNDATION_ERROR_OFFSET = 299999;

    private ErrorCodes() {
    }

    public static ErrorCode valueOf(int code) {
        if (code <= AUTHORIZATION_ERROR_OFFSET) {
            return Common.of(code);
        }
        if (code <= FOUNDATION_ERROR_OFFSET) {
            return Foundation.of(code);
        }
        return Common.ERROR_UNKNOWN_ERROR.errorCode();
    }

    public enum Common implements ErrorCodeBuilder {
        ERROR_UNKNOWN_ERROR(COMMON_ERROR_OFFSET + 1, "未知异常！"),
        ERROR_VALIDATION_FAILED(COMMON_ERROR_OFFSET + 2, "数据验证失败！"),
        ERROR_CACHE_OPERATION(COMMON_ERROR_OFFSET + 3, "操作缓存失败！"),
        ERROR_NOT_SUPPORTED(COMMON_ERROR_OFFSET + 4, "不支持该操作！"),
        ERROR_UNRECOGNIZED_VALUE(COMMON_ERROR_OFFSET + 5, "无法识别的值！"),
        ERROR_UNSUPPORTED_DATABASE(COMMON_ERROR_OFFSET + 6, "不支持的数据库类型!"),
        ERROR_SECURE_KEY_EMPTY(COMMON_ERROR_OFFSET + 7, "加密密钥不能为空!"),
        ERROR_UNSUPPORTED_ALGORITHM(COMMON_ERROR_OFFSET + 8, "不支持的加密算法!"),
        ERROR_UNAUTHORIZED(COMMON_ERROR_OFFSET + 9, "未认证的请求!"),
        ERROR_FORBIDDEN(COMMON_ERROR_OFFSET + 10, "请求被拒绝!"),
        ERROR_PARAMETER_TYPE(COMMON_ERROR_OFFSET + 11, "请求参数类型错误!"),
        ERROR_COMMUNICATION_FAILED(COMMON_ERROR_OFFSET + 12, "通信失败!"),
        ERROR_CRYPTOGRAPHY_FAILED(COMMON_ERROR_OFFSET + 13, "加密/解密失败!"),
        ERROR_PARAMETER_VALUE(COMMON_ERROR_OFFSET + 14, "请求参数值错误!");
        private int code;
        private String message;

        Common(int code, String message) {
            this.code = code;
            this.message = message;
        }

        @Override
        public int getCode() {
            return code;
        }

        @Override
        public String getMessage() {
            return message;
        }

        public static ErrorCode of(int code) {
            Optional<Common> common = Stream.of(values())
                .filter(c -> c.getCode() == code)
                .findFirst();
            return common.isPresent() ? common.get().errorCode()
                : Common.ERROR_UNKNOWN_ERROR.errorCode();
        }
    }

    public enum Authorization implements ErrorCodeBuilder {
        ERROR_TOKEN_MISSING(AUTHORIZATION_ERROR_OFFSET + 1, "请求未附带授权令牌！"),
        ERROR_INVALID_TOKEN(AUTHORIZATION_ERROR_OFFSET + 2, "授权令牌不合法！"),
        ERROR_TOKEN_EXPIRED(AUTHORIZATION_ERROR_OFFSET + 3, "授权令牌已过期！"),
        ERROR_ACCESS_DENIED(AUTHORIZATION_ERROR_OFFSET + 4, "权限不足！"),
        ERROR_BAD_CREDENTIAL(AUTHORIZATION_ERROR_OFFSET + 5, "用户名或密码错误！"),
        ERROR_AUTHENTICATION_FAILED(AUTHORIZATION_ERROR_OFFSET + 6, "身份认证失败！"),
        ERROR_AUTHORIZATION_FAILED(AUTHORIZATION_ERROR_OFFSET + 7, "授权失败！"),
        ERROR_USER_NOT_EXISTS(AUTHORIZATION_ERROR_OFFSET + 8, "用户不存在!"),
        ERROR_PASSWORD_MISMATCH(AUTHORIZATION_ERROR_OFFSET + 9, "初始密码不正确!"),
        ERROR_USER_STATUS_MISMATCH(AUTHORIZATION_ERROR_OFFSET + 10, "用户已被停用!");
        private int code;
        private String message;

        Authorization(int code, String message) {
            this.code = code;
            this.message = message;
        }

        @Override
        public int getCode() {
            return code;
        }

        @Override
        public String getMessage() {
            return message;
        }

        public static ErrorCode of(int code) {
            Optional<Authorization> authorization = Stream.of(values())
                .filter(c -> c.getCode() == code)
                .findFirst();
            return authorization.isPresent() ? authorization.get().errorCode()
                : Common.ERROR_UNKNOWN_ERROR.errorCode();
        }
    }

    public enum Foundation implements ErrorCodeBuilder {
        ;

        private int code;
        private String message;

        Foundation(int code, String message) {
            this.code = code;
            this.message = message;
        }

        @Override
        public int getCode() {
            return code;
        }

        @Override
        public String getMessage() {
            return message;
        }

        public static ErrorCode of(int code) {
            Optional<Foundation> foundation = Stream.of(values())
                .filter(c -> c.getCode() == code)
                .findFirst();
            return foundation.isPresent() ? foundation.get().errorCode()
                : Common.ERROR_UNKNOWN_ERROR.errorCode();
        }
    }



    interface ErrorCodeBuilder {

        int getCode();

        String getMessage();

        default ErrorCode errorCode() {
            return ErrorCode.of(getCode(), getMessage());
        }

        default ErrorCode errorCode(String message) {
            return ErrorCode.of(getCode(), message);
        }

        default ErrorCode errorCode(String format, Object... args) {
            String message;
            try {
                message = MessageFormat.format(format, args);
            } catch (Exception e) {
                LOGGER.error("生成错误信息失败！", e);
                message = getMessage();
            }
            return ErrorCode.of(getCode(), message);
        }
    }
}
